package com.itbaizhan;
/*MySql Blob类型简介
* Blob(全称：Binary Large Object 二进制大对象)。在MySql中，Blob
* 是一个二进制的用来存储图片，文件等数据的类型。操作 Blob类型的数据必须
* 使用PreparedStatement,因为Blob类型的数据无法使用字符串拼接
* 大多数情况，并不推荐直接把文件存放在 MySQL 数据库中，但如果应用
* 场景是文件与数据高度耦合，或者对文件安全性要求较高的，
* 那么将文件与数据存放在一起，即安全，又方便备份和迁移。*/

/* TinyBlob         最大255字节
* Blob          最大65K
* MediumBlob    最大16M
* LongBlob      最大4G*/

/*Blob类型使用的注意事项
实际使用中根据需要存入的数据大小定义不同的Blob类型。
如果存储的文件过大，数据库的性能会下降。*/

/*虽然MediumBlob允许保存最大值为16M，但MySql中默认支持的容量
为4194304即4M。我们可以通过修改Mysql的my.
ini文件中max_allowed_packet属性扩大支持的容量，
修改完毕后需要重启MySql服务。*/
//一般在C:\ProgramData\MySQL\MySQL Server 5.7/my.ini
import java.io.*;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

/**blob类型操作测试*/
//创建表
/*CREATE table movie (movieid int(11) not null auto_increment,
		moviename VARCHAR(30) DEFAULT null,
		poster mediumblob ,
		primary key(movieid)
		)ENGINE = innodb DEFAULT charset = utf8;*/
public class BlobTest {
    /*向Movie 表中插入数据*/
    //表中的poster 是Blob类型 是二进制  所以要用IO流
    //用InputStream 代表Blob类型
    public void insertMovie(String moviename, InputStream is){
        Connection connection = null;
        PreparedStatement ps = null;
        try{
            //获取连接
            connection = JdbcUtils.getConnection();
            //创建PreparedStatement对象
            ps = connection.prepareStatement("insert into movie values(default,?,?)");
            //绑定参数
            ps.setString(1,"moviename");
           //将输入流放入去
            ps.setBlob(2,is);
            //执行sql
            ps.executeUpdate();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JdbcUtils.closeResource(ps,connection);
        }
    }
        //获取Blob类型的信息
    //根据影片ID查询影片信息
    //取到整条数据的结果，再细分类型，取Blob
    public void selectMovieById(int movieid){
        Connection  connection = null;
        PreparedStatement ps = null;
        ResultSet rs = null;//取结果
        try{
            //获取连接
            connection = JdbcUtils.getConnection();
            //PreparedStatement对象
            ps = connection.prepareStatement("select * from movie where movieid = ?");
            //绑定参数
            ps.setInt(1,movieid);
            //执行SQL
            rs = ps.executeQuery();
            //获取查询的结果
            while (rs.next()){
                int id = rs.getInt("movieid");
                String name = rs.getString("moviename");
                System.out.println(id+" "+name);
                //获取BLob类型数据  现在将数据取出后再存到根目下（默认是根目录）
                //这是一个能操作Blob的对象，而不是拿到文件内容
                Blob blob = rs.getBlob("poster");
                //获取能够从Blob类型的列中读取数据的IO流
                //getBinaryStream() 这方法获取二进制流
                InputStream is = blob.getBinaryStream();
                //创建文件输出流对象 文件名字要注意，不可以相同，小心被复盖
                //不指定储存地址，默认在根目录下
                OutputStream os = new FileOutputStream(id+"_"+name+".png");
                //操作流完成文件的输出处理
                byte[] bytes = new byte[1024];
                int len;
                while ((len = is.read(bytes))!= -1){
                    os.write(bytes,0,len);
                }
                os.flush();
                is.close();
                os.close();

            }

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JdbcUtils.closeResource(rs,ps,connection);
        }
    }

    public static void main(String[] args) throws FileNotFoundException {
        BlobTest bt = new BlobTest();
        /*读图片的IO流交给SetBlob(),在数据库驱动会读取图片，所以创建IO流获取图片位置即可*/
        //创建读取文件的IO流
        //InputStream is = new FileInputStream(new File("e:/picture/2001.png"));
       // bt.insertMovie("java图片",is);
        //bt.selectMovieById(1);

    }
}
